﻿
#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Should;
using TechTalk.SpecFlow;
using UserStoryTrackerDemo.Controllers;
using UserStoryTrackerDemo.Data;
using UserStoryTrackerDemo.Domain.Pocos;
using UserStoryTrackerDemo.Specs.Steps.Watin;
using WatiN.Core;
using Table = TechTalk.SpecFlow.Table;
using TableRow = TechTalk.SpecFlow.TableRow;

#endregion

namespace UserStoryTrackerDemo.Specs.Steps
{
	[Binding]
	public class AddUserStorySteps : UserStoryStepsBase
	{
		private ViewResult _userStoryListResult;
		private ViewResult _createUserStoryResult;

		#region Given

		[Given(@"I filled out the form as follows")]
		public void GivenIFilledOutTheFormAsFollows(Table table)
		{
			foreach (var row in table.Rows)
			{
				var labelText = row["Label"];
				var value = row["Value"];
				WebBrowser.Current.TextFields.First(Find.ByLabelText(labelText)).TypeText(value);
			}
		}

		[Given(@"I am on the user story list page")]
		public void GivenIAmOnTheUserStoryListPage()
		{
			_userStoryListResult = NavigateToListPage();
		}

		[Given(@"I am on the create new user story page")]
		public void GivenIAmOnTheCreateNewUserStoryPage()
		{
			GivenIAmOnTheUserStoryListPage();
			WhenIClickCreateNewUserStory();
		}

		#endregion

		#region When

		[When(@"I click ""Create New User Story""")]
		public void WhenIClickCreateNewUserStory()
		{
			_createUserStoryResult =
				(ViewResult) new UserStoriesController(new Repository<UserStory>(new List<UserStory>(new List<UserStory>()
				                                                                                     	{
				                                                                                     		new UserStory()
				                                                                                     			{
				                                                                                     				Id = 1,
				                                                                                     				AsA = "Developer",
				                                                                                     				ICan = "test this page",
				                                                                                     				SoThatBecause =
				                                                                                     					"I can see it work",
				                                                                                     				Completed = false,
				                                                                                     			},
				                                                                                     		new UserStory()
				                                                                                     			{
				                                                                                     				Id = 2,
				                                                                                     				AsA = "Developer",
				                                                                                     				ICan =
				                                                                                     					"test this repository",
				                                                                                     				SoThatBecause =
				                                                                                     					"I can see it return data",
				                                                                                     				Completed = false,
				                                                                                     			},
				                                                                                     	}))).Create();

			WebBrowser.Current.Links.First(Find.ByText("Create New User Story")).Click();
		}

		[When(@"I save the user story")]
		public void WhenISaveTheUserStory()
		{
			WebBrowser.Current.Buttons.First(Find.ByValue("Save User Story")).Click();
		}

		#endregion

		#region Then

		[Then(@"I am on the create new user story page")]
		public void ThenIAmOnTheCreateNewUserStoryPage()
		{
			_createUserStoryResult.ShouldNotBeNull();
			WebBrowser.Current.Title.ShouldContain("Create User Story");
		}

		[Then(@"I should see a field labeled ""(.*)""")]
		public void ThenIShouldSeeAFieldLabledAsA(string field)
		{
			WebBrowser.Current.Text.ShouldContain(field);
		}

		//[Then(@"I should see a field labeled ""As a""")]
		//public void ThenIShouldSeeAFieldLabledAsA()
		//{
		//    var matchingFields = WebBrowser.Current.TextFields.Filter(Find.ByLabelText("As a"));
		//    matchingFields.Count.ShouldEqual(1);
		//}

		//[Then(@"I should see a field labeled ""I can""")]
		//public void ThenIShouldSeeAFieldLabledICan()
		//{
		//    var matchingFields = WebBrowser.Current.TextFields.Filter(Find.ByLabelText("I can"));
		//    matchingFields.Count.ShouldEqual(1);
		//}

		//[Then(@"I should see a field labeled ""so that/because""")]
		//public void ThenIShouldSeeAFieldLabledSoThatBecause()
		//{
		//    var matchingFields = WebBrowser.Current.TextFields.Filter(Find.ByLabelText("so that/because"));
		//    matchingFields.Count.ShouldEqual(1);
		//}

		[Then(@"I should be on the user story list page")]
		public void ThenIShouldBeOnTheUserStoryListPage()
		{
			WebBrowser.Current.Title.ShouldContain("User Stories");
		}

		[Then(@"the user story list entries should include")]
		public void ThenTheUserStoryListEntriesShouldInclude(Table table)
		{
			var stories = (from tableRow in WebBrowser.Current.Tables.First().TableRows
			               select tableRow.Elements
			               into elements
			               let asA = elements[0].OuterText
			               let iCan = elements[1].OuterText
			               let because = elements[2].OuterText
			               let completed = elements[3].OuterText
			               select new UserStory()
			                      	{
			                      		AsA = asA.Trim(),
			                      		Completed = completed.Equals("False") ? false : true,
			                      		ICan = iCan.Trim(),
			                      		SoThatBecause = because.Trim(),
			                      	}).ToList();


			//thanks steve sanderson for this awesome example of how to compare model data to specflow table
			Func<UserStory, TableRow, bool> equalityComparer = (userStory, row) => (row["As a"] == userStory.AsA
			                                                                        && row["I can"] == userStory.ICan
			                                                                        &&
			                                                                        row["so that/because"] ==
			                                                                        userStory.SoThatBecause
			                                                                        &&
			                                                                        row["Completed"] ==
			                                                                        (userStory.Completed ? "True" : "False")
			                                                                       );

			int lastMatchIndex = -1;
			foreach (var row in table.Rows)
			{
				lastMatchIndex = stories.FindIndex(0, story => equalityComparer(story, row));
				lastMatchIndex.ShouldBeInRange(0, (stories.Count - 1));
			}
		}

		#endregion
	}
}